using Abc.Core;
using Abc.Core.Entities;

using Furion.DatabaseAccessor;
using Furion.DependencyInjection;

using Mapster;

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Tool;

using Z.Linq;

namespace Abc.Application
{
    /// <summary>
    /// 数据配置
    /// </summary>
    //[ApiDescriptionSettings(Name = "DataConfig")]
    //[Injection(Proxy = typeof(LogDispatchProxy))]
    [ServiceFilter(typeof(ApiActionFilterAttribute))]
    public class DataConfigService : IDataConfigService, ITransient
    {
        public string CacheKey = "Table_DataConfig";
        private readonly ILogger<DataConfigService> _logger;
        private readonly IRepository<DataConfig> _dataConfigRepository;

        //private readonly IMemoryCache _memoryCache;
        private readonly ICacheService _cacheService;

        public DataConfigService(ILogger<DataConfigService> logger
        //, IMemoryCache memoryCache
        , IRepository<DataConfig> dataConfigRepository
        , ICacheService cacheService
         )
        {
            _logger = logger;
            // _memoryCache = memoryCache;
            //_memoryCache =  App.GetService<IMemoryCache>();
            _dataConfigRepository = dataConfigRepository;
            _cacheService = cacheService;
        }

        /// <summary>
        /// 新增或更新一条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<ResultData<string>> InsertOrUpdate(DataConfigInput input)
        {
            var resultdata = new ResultData<string>();
            if (string.IsNullOrWhiteSpace(input.PKey))
            {
                input.PKey = "";
            }
            if (input.Id > 0)
            {
                var dbentity = await _dataConfigRepository.FindAsync(input.Id);
                input.Adapt(dbentity);
                await _dataConfigRepository.UpdateAsync(dbentity);
            }
            else
            {
                var addentity = input.Adapt<DataConfig>();
                var newEntity = await _dataConfigRepository.InsertAsync(addentity);
            }
            await Refresh();
            resultdata.Succeeded = true;
            resultdata.Errors = "成功";
            return resultdata;
        }

        /// <summary>
        /// 删除一条
        /// </summary>
        /// <param name="id"></param>
        public async Task<ResultData<string>> Delete(int id)
        {
            var resultdata = new ResultData<string>();
            await _dataConfigRepository.DeleteAsync(id);
            await Refresh();

            resultdata.Succeeded = true;
            resultdata.Errors = "成功";
            return resultdata;
        }

        /// <summary>
        /// 查询所有
        /// </summary>
        /// <returns></returns>
        public async Task<List<DataConfigOut>> GetAll()
        {
            var entities = await _cacheService.GetDataConfigEntities();

            return entities.Adapt<List<DataConfigOut>>();
        }

        ///// <summary>
        ///// 查询一条[跟踪实体]
        ///// </summary>
        ///// <param name="id"></param>
        //public async Task<DataConfigDto> Find(int id)
        //{
        //    var dataconfigs = await AppEx.GetMemberCacheDataAsync<List<DataConfig>>(CacheKey);
        //    var dbentity =  dataconfigs;
        //    return dbentity.Adapt<DataConfigDto>();
        //}
        /// <summary>
        /// 查询一条[跟踪实体]
        /// </summary>
        /// <param name="id"></param>
        public async Task<DataConfigOut> Get(int id)
        {
            // var dbentity = await _dataConfigRepository.FirstOrDefaultAsync(o => o.Id == id, tracking: false);
            var entities = await _cacheService.GetDataConfigEntities();
            var dbentity = await entities.FirstOrDefaultAsync(o => o.Id == id);
            if (dbentity == null) return null;
            return dbentity.Adapt<DataConfigOut>();
        }

        /// <summary>
        /// 查询一条
        /// </summary>
        /// <param name="key"></param>
        public async Task<DataConfigOut> GetByKey(string key)
        {
            var entities = await _cacheService.GetDataConfigEntities();
            var dbentity = await entities.FirstOrDefaultAsync(o => o.Key.ToLower().Trim() == key.ToLower().Trim());
            if (dbentity == null) return null;
            return dbentity.Adapt<DataConfigOut>();
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="searchQuery"></param>
        /// <returns></returns>
        public async Task<PagedListToLayui<DataConfigOut>> GetAllByPageToLayui(DataConfigQuery searchQuery)
        {
            //var queryable= _dataConfigRepository.DetachedEntities.AsQueryable();
            //if (!string.IsNullOrWhiteSpace(searchQuery.KeyWords))
            //{
            //    var kw = searchQuery.KeyWords.ToLower();
            //    queryable = queryable.Where(o => o.No.Contains(kw));
            //}

            //var pageResult = _dataConfigRepository.DetachedEntities.AsQueryable().OrderByDescending(o => o.Id).ProjectToType<DataConfigDto>();
            //return await pageResult.ToPagedListToLayuiAsync(searchQuery.Page, searchQuery.Limit);

            var entities = await _cacheService.GetDataConfigEntities();
            return entities.Adapt<List<DataConfigOut>>().ToPagedListToLayui(searchQuery.Page, searchQuery.Limit);
        }

        /// <summary>
        /// 刷新配置
        /// </summary>
        /// <returns></returns>
        public async Task<List<DataConfig>> Refresh()
        {
            var entities = _dataConfigRepository.DetachedEntities.AsQueryable();
            var datas = await entities.ToListAsync();
            datas.SetMemoryCache(CacheKey);
            return datas;
        }

        #region 查询下拉树

        /// <summary>
        /// 查询菜单下来树
        /// </summary>
        /// <returns></returns>
        public async Task<Dtree> GetDtree(string pid = "")
        {
            var entities = await _cacheService.GetDataConfigEntities();
            var dtree = entities.Select(o => new DtreeEntity { id = o.Key, pid = o.PKey, name = o.Name, sort = o.Sort }).GetDtree(pid = "");
            return dtree;
        }

        #endregion 查询下拉树

        /// <summary>
        /// 获取系统设置
        /// </summary>
        /// <returns></returns>
        public async Task<TEntity> GetSetting<TEntity>(string pkey) where TEntity : new()
        {
            var entities = await _cacheService.GetDataConfigEntities();
            var settings = entities.Where(o => o.PKey == pkey).ToList();
            var settingdto = new TEntity();
            foreach (var setting in settings)
            {
                settingdto.PropertySetValue(setting.Key, setting.Value);
            }
            return settingdto;
        }

        /// <summary>
        /// 新增或修改设置
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="input">输入对象</param>
        /// <param name="Dpid">父级</param>
        /// <returns></returns>
        public async Task<ResultData<string>> AddOrUpdateSetting<T>(object input, string pkey)
        {
            var resultdata = new ResultData<string>();
            var dataconfigs = await _dataConfigRepository.Where(o => o.PKey == pkey).ToListAsync();
            var propertys = input.GetPropertyElements<T>();
            foreach (var property in propertys)
            {
                var dataconfig = dataconfigs.FirstOrDefault(o => o.Key != null && o.Key == property.Key && o.PKey == pkey);
                if (dataconfig == null)
                {
                    var newdataconfig = new DataConfig
                    {
                        PKey = pkey,
                        Key = property.Key,
                        Value = property.Value.GetValue("Value"),
                        Name = property.Value.GetValue("Description"),
                        IsEnable = true
                    };
                    var rnewdataconfig = await _dataConfigRepository.InsertAsync(newdataconfig);
                }
                else
                {
                    dataconfig = await _dataConfigRepository.FirstOrDefaultAsync(o => o.Key != null && o.Key == dataconfig.Key && o.PKey == pkey);
                    dataconfig.Value = property.Value.GetValue("Value");//值
                    dataconfig.Name = property.Value.GetValue("Description");//名称
                }
            }

            await Refresh();

            resultdata.Succeeded = true;
            resultdata.Errors = "保存成功";
            return resultdata;
        }

        /// <summary>
        /// 设置状态
        /// </summary>
        /// <param name="id"></param>
        /// <param name="state"></param>
        /// <param name="field">字段名</param>
        /// <returns></returns>
        public async Task<ResultData<string>> SetState(int id, bool state, string field)
        {
            var resultdata = new ResultData<string>();
            var entity = await _dataConfigRepository.FirstOrDefaultAsync(o => o.Id == id);

            switch (field.ToLower())
            {
                case "isenable":
                    {
                        entity.IsEnable = state;
                    }
                    break;
                //case "isdeleted":
                //    {
                //        entity.IsDeleted = state;
                //    }
                //    break;
                default:
                    break;
            }

            resultdata.Succeeded = true;
            resultdata.Errors = "成功";
            return resultdata;
        }

        #region 默认未启用

        ///// <summary>
        ///// 新增一条
        ///// </summary>
        ///// <param name="input"></param>
        ///// <returns></returns>
        //public async Task<ResultData<string>> Insert(DataConfigInput input)
        //{
        //    var resultdata = new ResultData<string>();
        //    var newEntity = await _dataConfigRepository.InsertAsync(input.Adapt<DataConfig>());
        //
        //    resultdata.Succeeded = true;
        //    resultdata.Errors = "成功";
        //    return resultdata;
        //}
        //
        ///// <summary>
        ///// 更新一条
        ///// </summary>
        ///// <param name="input"></param>
        ///// <returns></returns>
        //public async Task<ResultData<string>> Update(int id,DataConfigInput input)
        //{
        //    var resultdata=new ResultData<string>();
        //    var dbentity = await _dataConfigRepository.FindAsync(id);
        //    input.Adapt(dbentity);
        //    await _dataConfigRepository.UpdateAsync(dbentity);
        //
        //    resultdata.Succeeded = true;
        //    resultdata.Errors = "成功";
        //    return resultdata;
        //}
        //
        ///// <summary>
        ///// 新增或更新多条
        ///// </summary>
        ///// <param name="inputs"></param>
        ///// <returns></returns>
        //public async Task<ResultData<string>> Inserts(List<DataConfigInput> inputs)
        //{
        //    var resultdata = new ResultData<string>();
        //    var dbaddinputs = inputs.Adapt<List<DataConfig>>();
        //    await _dataConfigRepository.InsertAsync(dbaddinputs);
        //    resultdata.Succeeded = true;
        //    resultdata.Errors = "成功";
        //    return resultdata;
        //}
        ///// <summary>
        ///// 新增或更新多条
        ///// </summary>
        ///// <param name="inputs"></param>
        ///// <returns></returns>
        //public async Task<ResultData<string>> Updates(List<DataConfigInput> inputs)
        //{
        //    var resultdata = new ResultData<string>();
        //    var ids = inputs.Select(o => o.Id).ToList();
        //    var dbentitys = await _dataConfigRepository.Where(u => ids.Any(a => a == u.Id)).ToListAsync();
        //    inputs.Adapt(dbentitys);
        //    await _dataConfigRepository.UpdateAsync(dbentitys);
        //
        //    resultdata.Succeeded = true;
        //    resultdata.Errors = "成功";
        //    return resultdata;
        //}
        //
        ///// <summary>
        ///// 新增或更新多条
        ///// </summary>
        ///// <param name="input"></param>
        ///// <returns></returns>
        //public async Task<ResultData<string>> InsertOrUpdates(List<DataConfigInput> inputs)
        //{
        //    var resultdata = new ResultData<string>();
        //    if (inputs.Any(o => o.Id > 0))
        //    {
        //        var updates = inputs.Where(o => o.Id > 0);
        //        var ids = updates.Select(o=>o.Id).ToList();
        //        var dbentity =  _dataConfigRepository.Where(o=> ids.Any(a=>a==o.Id));
        //        inputs.Adapt(dbentity);
        //        await  _dataConfigRepository.UpdateAsync(dbentity);
        //    }
        //    else
        //    {
        //       var adds = inputs.Where(o => o.Id <= 0);
        //       await _dataConfigRepository.InsertAsync(adds.Adapt<List<DataConfig>>());
        //
        //    }
        //    resultdata.Succeeded = true;
        //    resultdata.Errors = "成功";
        //    return resultdata;
        //}
        //
        //

        ///// <summary>
        ///// 分页查询
        ///// </summary>
        ///// <param name="searchQuery"></param>
        ///// <returns></returns>
        //public async Task<PagedList<DataConfigDto>> GetAllByPage(DataConfigQuery searchQuery)
        //{
        //    //var queryable= _dataConfigRepository.DetachedEntities.AsQueryable(tracking:false);
        //    //if (!string.IsNullOrWhiteSpace(searchQuery.KeyWords))
        //    //{
        //    //    var kw = searchQuery.KeyWords.ToLower();
        //    //    queryable = queryable.Where(o => o.No.Contains(kw));
        //    //}
        //    var pageResult = _dataConfigRepository.DetachedEntities.AsQueryable().OrderByDescending(o => o.Id).ProjectToType<DataConfigDto>();
        //
        //    return await pageResult.ToPagedListAsync(searchQuery.Page, searchQuery.Limit);
        //}
        //
        //
        //
        //

        #endregion 默认未启用
    }

    public interface IDataConfigService
    {
        /// <summary>
        /// 新增或更新一条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        Task<ResultData<string>> InsertOrUpdate(DataConfigInput input);

        /// <summary>
        /// 删除一条
        /// </summary>
        /// <param name="id"></param>
        Task<ResultData<string>> Delete(int id);

        ///// <summary>
        ///// 查询一条
        ///// </summary>
        ///// <param name="id"></param>
        //Task<DataConfigDto> Find(int id);
        /// <summary>
        /// 查询所有
        /// </summary>
        /// <returns></returns>
        Task<List<DataConfigOut>> GetAll();

        /// <summary>
        /// 查询一条
        /// </summary>
        /// <param name="id"></param>
        Task<DataConfigOut> Get(int id);

        /// <summary>
        /// 查询一条
        /// </summary>
        /// <param name="key"></param>
        Task<DataConfigOut> GetByKey(string key);

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="searchQuery"></param>
        /// <returns></returns>
        Task<PagedListToLayui<DataConfigOut>> GetAllByPageToLayui(DataConfigQuery searchQuery);

        /// <summary>
        /// 查询下拉树
        /// </summary>
        /// <returns></returns>
        Task<Dtree> GetDtree(string pid = "");

        /// <summary>
        /// 新增或修改设置
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="input">输入对象</param>
        /// <param name="Dpid">父级</param>
        /// <returns></returns>
        Task<ResultData<string>> AddOrUpdateSetting<T>(object input, string Dpid);

        /// <summary>
        /// 获取系统设置
        /// </summary>
        /// <returns></returns>
        Task<TEntity> GetSetting<TEntity>(string dpid) where TEntity : new();

        /// <summary>
        /// 设置状态
        /// </summary>
        /// <param name="id"></param>
        /// <param name="state"></param>
        /// <param name="field">字段名</param>
        /// <returns></returns>
        Task<ResultData<string>> SetState(int id, bool state, string field);

        #region 默认未启用

        ///// <summary>
        ///// 新增一条
        ///// </summary>
        ///// <param name="input"></param>
        ///// <returns></returns>
        //Task<ResultData<string>> Insert(DataConfigInput input);
        //
        ///// <summary>
        ///// 更新一条
        ///// </summary>
        ///// <param name="input"></param>
        ///// <returns></returns>
        //Task<ResultData<string>> Update(int id,DataConfigInput input);
        ///// <summary>
        ///// 新增或更新一条
        ///// </summary>
        ///// <param name="input"></param>
        ///// <returns></returns>
        //Task<ResultData<string>> Inserts(List<DataConfigInput> inputs);
        ///// <summary>
        ///// 新增或更新多条
        ///// </summary>
        ///// <param name="inputs"></param>
        ///// <returns></returns>
        //Task<ResultData<string>> Updates(List<DataConfigInput> inputs);
        ///// <summary>
        ///// 新增或更新多条
        ///// </summary>
        ///// <param name="inputs"></param>
        ///// <returns></returns>
        //Task<ResultData<string>> InsertOrUpdates(List<DataConfigInput> inputs);

        ///// <summary>
        ///// 分页查询
        ///// </summary>
        ///// <param name="searchQuery"></param>
        ///// <returns></returns>
        //Task<PagedList<DataConfigDto>> GetAllByPage(DataConfigQuery searchQuery);

        #endregion 默认未启用
    }
}